package br.com.fgv.tcc.fgv.imovel.dao;

import br.com.fgv.tcc.fgv.imovel.util.HibernateUtil;
import static br.com.fgv.tcc.fgv.imovel.util.HibernateUtil.getSession;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;
import java.util.logging.Level;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author diego
 */
/**
 * Esta classe é responsável por conter as operações genéricas para realização
 * do acesso aos dados do sistema.
 * 
* @author Adão
 * 
* @param
 */
public class HibernateGenericDao implements Dao {

    private static Logger logger;
    private Class classePersistida;
    private String ordenacao;
    private long iniTime;

    public HibernateGenericDao(Class persistentClass) {
        BasicConfigurator.configure();
        this.classePersistida = persistentClass;
        logger = Logger.getLogger(classePersistida);
    }

    public String getOrdenacao() {
        return ordenacao;
    }

    public void setOrdenacao(String ordenacao) {
        this.ordenacao = ordenacao;
    }

    @Override
    public void salvar(Object obj) {
        iniTime = System.currentTimeMillis();
        try {
            logger.info("Executando  salvar");
            HibernateUtil.beginTransaction();
            HibernateUtil.getSession().save(obj);
            HibernateUtil.commitTransaction();

        } catch (HibernateException hibernateException) {
            HibernateUtil.cancelar();
            logger.error("Erro ao Executar  salvar registro");
            throw hibernateException;
        } finally {
            logger.info("Registro salvo executado em: " + (System.currentTimeMillis() - iniTime) + "ms");
        }
    }

    @Override
    public Object recuperar(Serializable id) {
        iniTime = System.currentTimeMillis();
        logger.info("Executando  recuperar");
        Criteria c;
        try {
            c = HibernateUtil.getSessionFactory().openSession().createCriteria(classePersistida);
            c.add(Restrictions.idEq(id));
            logger.info("Registro salvo executado em: " + (System.currentTimeMillis() - iniTime) + "ms");
        } catch (HibernateException hibernateException) {
            logger.error("Erro ao Executar  recuperar, id do registro: " + id);
            throw hibernateException;

        }
        return c.uniqueResult();
    }

    @Override
    public List buscar(Criteria crit) {

        if (ordenacao != null) {
            crit.addOrder(Order.asc(ordenacao));
        }
        return crit.list();

        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public List listarTodos() {
        logger.info("Inicio do listar todos Objeto" + classePersistida.getSimpleName());
        try {
            Criteria c = HibernateUtil.getSessionFactory().openSession().createCriteria(classePersistida);

            if (ordenacao != null) {
                c.addOrder(Order.asc(ordenacao));
            }
            return c.list();
        } catch (HibernateException e) {
            throw e;
        }

    }

    @Override
    public void atualizar(Object obj) {
        iniTime = System.currentTimeMillis();
        try {
            logger.info("Executando  atualizar");

            System.out.print("Executando  atualizar");
            HibernateUtil.beginTransaction();
            HibernateUtil.getSession().update(obj);
            HibernateUtil.commitTransaction();

        } catch (HibernateException hibernateException) {
            HibernateUtil.cancelar();
            logger.error("Erro ao Executar  atualizar registro");
            throw hibernateException;
        } finally {
            logger.info("Registro atualizado executado em: " + (System.currentTimeMillis() - iniTime) + "ms");
        }
    }

    @Override
    public void salvarAtualizar(Object obj) {
        iniTime = System.currentTimeMillis();
        try {
            logger.info("Executando  salvar/atualizar");
            HibernateUtil.beginTransaction();
            HibernateUtil.getSession().saveOrUpdate(obj);
            HibernateUtil.commitTransaction();

        } catch (HibernateException hibernateException) {
            HibernateUtil.cancelar();
            logger.error("Erro ao Executar  salvar/atualizar registro");
            throw hibernateException;
        } finally {
            logger.info("Registro salvo/atualizado executado em: " + (System.currentTimeMillis() - iniTime) + "ms");
        }
    }

    @Override
    public void remover(Object obj) {
        iniTime = System.currentTimeMillis();
        try {
            logger.info("Executando   remover");
            HibernateUtil.beginTransaction();
            HibernateUtil.getSession().delete(obj);
            HibernateUtil.commitTransaction();

        } catch (HibernateException hibernateException) {
            HibernateUtil.cancelar();
            logger.error("Erro ao Executar  remover registro");
            throw hibernateException;
        } finally {
            logger.info("Registro removido executado em: " + (System.currentTimeMillis() - iniTime) + "ms");
        }
    }
}
